mutate, group_by

Aula 10, M2

Carolina Musso

Sala de Situação - UnB

Esta semana

Aula 10 - Criando novas variáveis e resumindo

Função mutate() e group_by()

Aula 11 - Tabela

Mais sobre o pacote flextable: cores e bordas

Leituras para aprofundamento: as mesmas!

Função select() e filter()

  • trabalhando com colunas - seleciona, reordena…

  • filtra linhas

  • Nada disso mudou a essência dos dados!!

    • Só mudou de lugar ou exlcuiu alguma coisa …

Hoje:

  • As vezes quer calcular coisas novas!

    • Indicadores;

    • Estatísticas descritivas básicas;

    • Novas variáveis…

mutate ()

Cria novas colunas ou substitui as existentes

meus_dados %>% 
  mutate(nome_nova_coluna=funcao(nome_coluna_que_quero_usar)

Exemplo 1

  • A altura está em cm, eu quero a altura em metros.
  • Ele vai calcular para cada um, o resultado correspondente.
ebola %>% 
  select( ht_cm) %>% # só para simplificar a base
  mutate(ht_m=ht_cm/100)
# A tibble: 5,888 × 2
   ht_cm  ht_m
   <dbl> <dbl>
 1    48  0.48
 2    59  0.59
 3   238  2.38
 4   135  1.35
 5    71  0.71
 6   116  1.16
 7    87  0.87
 8    11  0.11
 9   226  2.26
10   174  1.74
# ℹ 5,878 more rows

Exemplo 2

  • Eu queria a altura em metros para calcular o IMC, posso continuar o cálculo com a nova variável.
ebola %>% 
  select(wt_kg, ht_cm) %>% 
  mutate(ht_m=ht_cm/100,
         imc=wt_kg/ht_m^2)
# A tibble: 5,888 × 4
   wt_kg ht_cm  ht_m   imc
   <dbl> <dbl> <dbl> <dbl>
 1    27    48  0.48 117. 
 2    25    59  0.59  71.8
 3    91   238  2.38  16.1
 4    41   135  1.35  22.5
 5    36    71  0.71  71.4
 6    56   116  1.16  41.6
 7    47    87  0.87  62.1
 8     0    11  0.11   0  
 9    86   226  2.26  16.8
10    69   174  1.74  22.8
# ℹ 5,878 more rows

Exemplo 3

  • Fazer o cálculo com os valores de uma coluna só.

  • O que acontece?

ebola %>% 
  filter(!is.na(age)) %>% 
  select(age) %>% 
  mutate(idade_media=mean(age)) # ou na.rm=T 
# A tibble: 5,802 × 2
     age idade_media
   <dbl>       <dbl>
 1     2        16.1
 2     3        16.1
 3    56        16.1
 4    18        16.1
 5     3        16.1
 6    16        16.1
 7    16        16.1
 8     0        16.1
 9    61        16.1
10    27        16.1
# ℹ 5,792 more rows

CUIDADO!!

  • Ele faz a conta para a coluna!

  • Fazer a conta para uma linha é meio chato!

    • Não é simples como no excel.

    • Mas, se precisar! Pesquise as funções:

      • rowwise()

      • c_across()

group_by()

Vimos que:

  • O mutate() cria novas colunas (ou substitui uma existente se usar o mesmo nome de variável).
  • Vimos que ele não reduz a base de dados.

Veja esse exemplo

  • Para calcular a média de idade
ebola %>% 
  select(age) %>% 
  mutate(idade_media=mean(age, na.rm=T)) 
# A tibble: 5,888 × 2
     age idade_media
   <dbl>       <dbl>
 1     2        16.1
 2     3        16.1
 3    56        16.1
 4    18        16.1
 5     3        16.1
 6    16        16.1
 7    16        16.1
 8     0        16.1
 9    61        16.1
10    27        16.1
# ℹ 5,878 more rows

Mas agora queremos algo assim:

O group_by()

Agrupar

ebola %>% 
  select(gender, age) %>% 
  group_by(gender) 
# A tibble: 5,888 × 2
# Groups:   gender [3]
   gender   age
   <chr>  <dbl>
 1 m          2
 2 f          3
 3 m         56
 4 f         18
 5 m          3
 6 f         16
 7 f         16
 8 f          0
 9 m         61
10 f         27
# ℹ 5,878 more rows
  • Uai… ele não fez nada?

E se eu acrescentar um mutate()?

Agrupar + alguma conta!

ebola %>%
  select(gender, age) %>% 
  group_by(gender) %>% 
  mutate(idade_media=mean(age, na.rm=T))
# A tibble: 5,888 × 3
# Groups:   gender [3]
   gender   age idade_media
   <chr>  <dbl>       <dbl>
 1 m          2        19.6
 2 f          3        12.7
 3 m         56        19.6
 4 f         18        12.7
 5 m          3        19.6
 6 f         16        12.7
 7 f         16        12.7
 8 f          0        12.7
 9 m         61        19.6
10 f         27        12.7
# ℹ 5,878 more rows

O que perceberem?

  • Melhorou um pouco…

    • Mas parece que ainda tenho muita coisa repetida de que não preciso, não é? Preciso reduzir o banco

group_by() + summarise()

ebola %>% 
  select(gender, age) %>% 
  group_by(gender) %>% 
  summarise(idade_media=mean(age, na.rm=T)) # tambem aceita summarize
# A tibble: 3 × 2
  gender idade_media
  <chr>        <dbl>
1 f             12.7
2 m             19.6
3 <NA>          14.9

Tudo junto misturado!

ebola %>% 
  select(gender, age, wt_kg, ht_cm) %>% 
  mutate(ht_m=ht_cm/100,
         IMC=wt_kg/ht_m^2) %>% 
  group_by(gender) %>% 
  summarise(idade_media=mean(age, na.rm=T),
            IMC_medio=mean(IMC))
# A tibble: 3 × 3
  gender idade_media IMC_medio
  <chr>        <dbl>     <dbl>
1 f             12.7      55.5
2 m             19.6      38.4
3 <NA>          14.9      46.0
  • Note que
ebola %>% 
  #select(gender, age, wt_kg, ht_cm) %>% 
  mutate(ht_m=ht_cm/100,
         IMC=wt_kg/ht_m^2) %>% 
  group_by(gender) %>% 
  summarise(idade_media=mean(age, na.rm=T),
            IMC_medio=mean(IMC))
# A tibble: 3 × 3
  gender idade_media IMC_medio
  <chr>        <dbl>     <dbl>
1 f             12.7      55.5
2 m             19.6      38.4
3 <NA>          14.9      46.0

E esses NAs?

  • “Not Available” - um valor faltante (missing value). O que é bem diferente de um valor 0 (Zero), por exemplo.

Para saber mais, veja os capítulos:

Exemplo:

Com o mutate()

ebola %>% 
  select(gender, age) %>% 
  mutate(idade_media=mean(age))
# A tibble: 5,888 × 3
   gender   age idade_media
   <chr>  <dbl>       <dbl>
 1 m          2          NA
 2 f          3          NA
 3 m         56          NA
 4 f         18          NA
 5 m          3          NA
 6 f         16          NA
 7 f         16          NA
 8 f          0          NA
 9 m         61          NA
10 f         27          NA
# ℹ 5,878 more rows
  • Tem pelo menos um NA em alguma dos valores de idade

  • Afinal, você somar um número que você não sabe, vai resultar em algo que você não sabe.

Exemplo:

Tentando o group_by + summarise()

ebola %>% 
  group_by(gender) %>% 
  summarise(idade_media=mean(age))
# A tibble: 3 × 2
  gender idade_media
  <chr>        <dbl>
1 f             12.7
2 m             19.6
3 <NA>          NA  
  • NA em ambas essas variáveis

O que podemos fazer?

Jogar fora os NA

ebola %>% 
  filter(!is.na(gender)) %>% 
  group_by(gender) %>% 
  summarise(idade_media=mean(age))
# A tibble: 2 × 2
  gender idade_media
  <chr>        <dbl>
1 f             12.7
2 m             19.6
  • Cuidado! Nem sempre é o que você quer

O que podemos fazer?

Ignorar os NA apenas para as contas

ebola %>% 
  group_by(gender) %>% 
  summarise(idade_media=mean(age, na.rm=T))
# A tibble: 3 × 2
  gender idade_media
  <chr>        <dbl>
1 f             12.7
2 m             19.6
3 <NA>          14.9

Isso é só a ponta do iceberg

  • Há muitas funções auxiliares

  • Veja os capítulos sugeridos para mais dicas sobre valores faltantes

  • Há outras tecnicas mais avaçadas: imputar dados

    • Não vamos falar disso, é só para saberem que existe.

Vamos aos exercícios!